/*
 * Copyright (c) 2007 Compl Yue Still, All Rights Reserved.
 */

package hbi.wire.java.host;

import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;

class TypedArrayContent implements DataTag
{

    public Object getTagValue()
    {
        return elements;
    }

    private final DataTag componentReceiver;

    final Class<?> componentType;

    TypedArrayContent(Class<?> elementType, int dimension,
        DataTag elementReceiver)
    {
        if (dimension > 1)
        {
            TypedArrayContent innerArrayContent = new TypedArrayContent(
                elementType, dimension - 1, elementReceiver);
            this.componentType = Array.newInstance(
                innerArrayContent.componentType, 0).getClass();
            this.componentReceiver = innerArrayContent;
        }
        else
        {
            assert dimension == 1;
            this.componentType = elementType;
            this.componentReceiver = elementReceiver;
        }
    }

    public void reset()
    {
        this.elements = null;
        this.readPos = 0;
    }

    private Object elements = null;

    private int readPos = 0;

    public boolean processIncomingData(ByteBuffer buffer) throws IOException
    {
        if (elements == null)
        {
            if (buffer.remaining() < 4) return false;
            int length = buffer.getInt();
            if (length < 0)
                throw new SecurityException("Too big array length: " + length);
            elements = Array.newInstance(componentType, length);
        }

        tag_scan: while (buffer.hasRemaining())
        {
            if (componentReceiver.processIncomingData(buffer))
            {
                Array.set(elements, readPos++, componentReceiver.getTagValue());
                componentReceiver.reset();
                if (readPos >= Array.getLength(elements)) return true;
            }
            else
            {
                break tag_scan;
            }
        }

        return false;
    }

}
